// Copyright Gary Evans 2006-2007.

using System;
using System.Collections.Generic;
using System.Text;

using NUnit.Framework;

using Taumuon.Jabuka.Physics.Collision;

namespace Taumuon.Jabuka.Physics.Test
{
    /// <summary>
    /// Tests the Sphere collision primitive.
    /// </summary>
    [TestFixture]
    public class TestSphere
    {
        /// <summary>
        /// Tests that Sphere c'tor verifies its EulerRigidBody
        /// </summary>
		[Test]
        [ExpectedException(typeof(ArgumentNullException))]
		public void TestSphereNullEulerRigidBody()
		{
            Sphere sphere = new Sphere(null, 0.0);
		}

		/// <summary>
		/// Tests that exception thrown when radius is negative.
		/// </summary>
		[Test]
        [ExpectedException(typeof(ArgumentException))]
		public void TestSphereRadiusLessThanZero()
		{
            Sphere sphere = new Sphere(new MockEulerRigidBody(), -1.0);
		}

		/// <summary>
		/// Tests that the radius is returned as set in the c'tor.
		/// </summary>
		[Test]
		public void TestSphereRadiusProperty()
		{
            Sphere sphere = new Sphere(new MockEulerRigidBody(), 2.0);
            Assert.AreEqual(2.0, sphere.Radius);
		}

        /// <summary>
        /// Tests the Sphere's ICloneable interface
        /// </summary>
        [Test]
        public void TestSphereClone()
        {
            MockEulerRigidBody eulerRigidBody = new
                MockEulerRigidBody();
            MockEulerRigidBody eulerRigidBodyClone = new
                MockEulerRigidBody();
            Sphere sphere = new Sphere(eulerRigidBody, 1.5);

            Sphere sphere2 = sphere.Clone() as Sphere;
            Assert.IsNotNull(sphere2);
            Assert.IsFalse(object.ReferenceEquals(sphere, sphere2));
            Assert.IsFalse(object.ReferenceEquals(
                sphere.EulerRigidBody, sphere2.EulerRigidBody));
            // Check the MemberwiseClone has been called
            Assert.AreEqual(1.5, sphere2.Radius);
            // Check that the sphere has called Clone on its member
            //  and received the cloned object.
            Assert.IsFalse(object.ReferenceEquals(
                sphere2.EulerRigidBody, eulerRigidBodyClone ));
        }

		/// <summary>
		/// Tests a sphere's values are correctly assigned from another sphere.
		/// </summary>
		[Test]
		public void TestSphereAssignFromSphere()
		{
			MockEulerRigidBody eulerRigidBody = new
				MockEulerRigidBody();
			MockEulerRigidBody eulerRigidBody2 = new
				MockEulerRigidBody();
			Sphere sphere = new Sphere(eulerRigidBody, 1.5);
			Sphere sphere2 = new Sphere(eulerRigidBody2, 2.5);

			Assert.IsFalse(eulerRigidBody.AssignFromCalled, "AssignFromEulerRigidBody should not yet have been called");
			sphere.AssignFromSphere(sphere2);

			Assert.AreEqual(2.5, sphere.Radius, "Radius not as expected");
			Assert.IsTrue(eulerRigidBody.AssignFromCalled, "AssignFromEulerRigidBody should have been called");
		}
    }
}
